package zcj.stu.C41;

import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.*;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.core.type.AnnotationMetadata;

import java.util.List;

public class C41 {
    public static void main(String[] args) {
        GenericApplicationContext context = new GenericApplicationContext();
        DefaultListableBeanFactory beanFactory = context.getDefaultListableBeanFactory();
        beanFactory.setAllowBeanDefinitionOverriding(false);//springboot中默认是false
        context.registerBean("config", Config.class);
        context.registerBean(ConfigurationClassPostProcessor.class);
        AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
        context.refresh();
        //查看容器中的bean
        for (String beanDefinitionName : context.getBeanDefinitionNames()) {
            System.out.println(beanDefinitionName);
        }
//        System.out.println(context.getBean(Bean1.class));
        context.getBeansOfType(Bean1.class).forEach(((s, bean1) -> {
            System.out.println(bean1);
        }));
    }

    @Configuration
//    @Import(MyImportSelector.class)
    @EnableAutoConfiguration//底层@Import(***ImportSelector.class)
    static class Config {
        @Bean
        public Bean1 bean1() {
            return new Bean1("本项目");
        }
//        @Bean
//        public Bean1 myBean11(){
//            return new Bean1("本项目1");
//        }
    }
    static class MyImportSelector implements DeferredImportSelector {//ImportSelector DeferredImportSelector 推迟导入配置类的加载

        @Override
        public String[] selectImports(AnnotationMetadata importingClassMetadata) {
//            return new String[]{ExternConfig1.class.getName(),ExternConfig2.class.getName()};
            List<String> configs = SpringFactoriesLoader.loadFactoryNames(MyImportSelector.class, null);
            System.out.println(configs);
            return configs.toArray(new String[0]);
        }
    }

    @Configuration
    static class ExternConfig1 {
        @Bean
        @ConditionalOnMissingBean//如果没有该种类型的bean了就加入容器
        public Bean1 bean1() {
            return new Bean1("外部的");
        }
    }

    @Configuration
    static class ExternConfig2 {
        @Bean
        public Bean2 bean2() {
            return new Bean2();
        }
    }

    static class Bean1 {
        private String name;

        public Bean1() {
        }

        public Bean1(String name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return "Bean1{" +
                    "name='" + name + '\'' +
                    '}';
        }
    }

    static class Bean2 {

    }
}
